package service

import (
	"context"
	"fmt"
	"time"

	"github.com/jinzhu/now"
	jsoniter "github.com/json-iterator/go"
	"zhonghui/console/structs"
	"zhonghui/console/warehouse/dbx"
	"zhonghui/console/warehouse/dbx/cache_main"
	"zhonghui/console/warehouse/dbx/db_zh_kernel_slave"
	"zhonghui/console/warehouse/helperx"
	"zhonghui/console/warehouse/modelx/model_zh_kernel"
)

// GetClickDataForTask 获取一个任务的点击数据
func GetClickDataForTask(task *model_zh_kernel.SysTask) *structs.ClickChartsData {
	data := structs.ClickChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("click_data_task_id_%d", task.ID))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("task_id = ? and kind = ?", task.ID, structs.ReportKindSmsClick).Distinct("phone").Count(&total)
	data.Total = total

	// 查询任务创建之后72小时的数据
	kv := make([]structs.ChartsKV, 0)
	db_zh_kernel_slave.Client().Table("report").
		Where("task_id = ? and kind = ? and created_at <= ?", task.ID, structs.ReportKindSmsClick, task.CreateTime.Add(72*time.Hour).Format(helperx.TimeLayoutCommon)).
		Select("count(distinct phone) as value, DATE_FORMAT(created_at, '%m-%d %H:00') as `key`").
		Group("`key`").
		Order("`key` asc").
		Find(&kv)

	data.Lines = CombineKVByHour(kv, task.CreateTime, task.CreateTime.Add(72*time.Hour))

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

// GetMpDataForTask 获取小程序的访问数据
func GetMpDataForTask(task *model_zh_kernel.SysTask) *structs.MpChartsData {
	data := structs.MpChartsData{}
	return &data

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("mp_data_task_id_%d", task.ID))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("task_id = ? and kind = ?", task.ID, structs.ReportKindViewMp).Distinct("phone").Count(&total)
	data.Total = total

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

// GetWeComDataForTask 获取企微的访问数据
func GetWeComDataForTask(task *model_zh_kernel.SysTask) *structs.WeComChartsData {
	data := structs.WeComChartsData{}
	return &data

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("we_com_data_task_id_%d", task.ID))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("task_id = ? and kind = ?", task.ID, structs.ReportKindWecom).Distinct("phone").Count(&total)
	data.Total = total

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

// GetInsurancePolicyDataForTask 获取访问投保成功页面数据
func GetInsurancePolicyDataForTask(task *model_zh_kernel.SysTask) *structs.InsurancePolicyChartsData {
	data := structs.InsurancePolicyChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("insurance_policy_data_task_id_%d", task.ID))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("task_id = ? and kind = ?", task.ID, structs.ReportKindInsurancePolicy).Distinct("phone").Count(&total)
	data.Total = total

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

// GetInsurancePolicyUpgradeDataForTask 获取访问投保成功-升级页面数据
func GetInsurancePolicyUpgradeDataForTask(task *model_zh_kernel.SysTask) *structs.InsurancePolicyUpgradeChartsData {
	data := structs.InsurancePolicyUpgradeChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("insurance_policy_upgrade_data_task_id_%d", task.ID))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("task_id = ? and kind = ?", task.ID, structs.ReportKindInsurancePolicyUpgrade).Distinct("phone").Count(&total)
	data.Total = total

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

// MakeKVByHourRange 构造一个指定时间的kv分段数据，每小时一个
func MakeKVByHourRange(start, end time.Time) []structs.ChartsKV {
	kv := make([]structs.ChartsKV, 0)

	for start.Before(end.Add(time.Hour)) {
		kv = append(kv, structs.ChartsKV{
			Key:   start.Format("01-02 15:00"),
			Value: 0,
		})
		start = start.Add(time.Hour)
	}

	return kv
}

// CombineKVByHour 合并真实kv数据和结构数据
func CombineKVByHour(kv []structs.ChartsKV, start, end time.Time) []structs.ChartsKV {
	kvMap := make(map[string]structs.ChartsKV)
	for _, v := range kv {
		kvMap[v.Key] = v
	}

	kvNew := make([]structs.ChartsKV, 0)
	for start.Before(end.Add(time.Hour)) {
		k := start.Format("01-02 15:00")
		if _, ok := kvMap[k]; ok {
			kvNew = append(kvNew, kvMap[k])
		} else {
			kvNew = append(kvNew, structs.ChartsKV{
				Key:   k,
				Value: 0,
			})
		}
		start = start.Add(time.Hour)
	}

	return kvNew
}

func GetTotalSmsCharts() *structs.TotalSmsChartsData {
	data := structs.TotalSmsChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_sms_charts_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var count int64
	db_zh_kernel_slave.Client().Model(model_zh_kernel.Report{}).Where("kind = ?", structs.ReportKindSmsSend).Count(&count)
	data.Total = count

	var count2 int64
	db_zh_kernel_slave.Client().Model(model_zh_kernel.Report{}).Where("kind = ?", structs.ReportKindSmsFail).Count(&count2)
	data.Fail = count2

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

func GetTotalClickData() *structs.ClickChartsData {
	data := structs.ClickChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_click_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("kind = ?", structs.ReportKindSmsClick).Count(&total)
	data.Total = total

	// 查询任务创建之后72小时的数据
	kv := make([]structs.ChartsKV, 0)
	db_zh_kernel_slave.Client().Table("report").
		Where("kind = ? and created_at >= ?", structs.ReportKindSmsClick, time.Now().Add(-72*time.Hour).Format(helperx.TimeLayoutCommon)).
		Select("count(1) as value, DATE_FORMAT(created_at, '%m-%d %H:00') as `key`").
		Group("`key`").
		Order("`key` asc").
		Find(&kv)

	data.Lines = CombineKVByHour(kv, time.Now().Add(-72*time.Hour), time.Now())

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

func GetTotalMpData() *structs.MpChartsData {
	data := structs.MpChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_mp_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("kind = ?", structs.ReportKindViewMp).Count(&total)
	data.Total = total

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

func GetTotalWeComData() *structs.WeComChartsData {
	data := structs.WeComChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_we_com_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("kind = ?", structs.ReportKindWecom).Count(&total)
	data.Total = total

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

func GetTotalInsurancePolicyData() *structs.InsurancePolicyChartsData {
	data := structs.InsurancePolicyChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_insurance_policy_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("kind = ?", structs.ReportKindInsurancePolicy).Distinct("phone").Count(&total)
	data.Total = total

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

func GetTotalInsurancePolicyUpgradeData() *structs.InsurancePolicyChartsData {
	data := structs.InsurancePolicyChartsData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_insurance_policy_upgrade_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	var total int64
	db_zh_kernel_slave.Client().Table("report").Where("kind = ?", structs.ReportKindInsurancePolicyUpgrade).Distinct("phone").Count(&total)
	data.Total = total

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

func GetTotalUserSummary() *structs.TotalUserSummaryData {
	data := structs.TotalUserSummaryData{}

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_user_summary_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	db_zh_kernel_slave.Client().Model(model_zh_kernel.Report{}).Where("kind = ?", structs.ReportKindSmsClick).Distinct("phone").Count(&data.UV)
	db_zh_kernel_slave.Client().Model(model_zh_kernel.Report{}).Where("kind = ? and created_at >= ?", structs.ReportKindSmsClick, now.BeginningOfDay().Format(helperx.TimeLayoutCommon)).Distinct("phone").Count(&data.UVToday)

	db_zh_kernel_slave.Client().Model(model_zh_kernel.Report{}).Where("kind = ?", structs.ReportKindViewMp).Distinct("phone").Count(&data.MpUV)
	db_zh_kernel_slave.Client().Model(model_zh_kernel.Report{}).Where("kind = ? and created_at >= ?", structs.ReportKindViewMp, now.BeginningOfDay().Format(helperx.TimeLayoutCommon)).Distinct("phone").Count(&data.MpUVToday)

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return &data
}

func GetTotalUserAreaData() []structs.UserPropChartsData {
	data := make([]structs.UserPropChartsData, 0)

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_user_area_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	db_zh_kernel_slave.Client().Model(model_zh_kernel.SysSmsRecord{}).
		Where("area != ''").
		Group("area").Select("area as name, count(*) as num").Order("num desc").Limit(10).Find(&data)

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return data
}

func GetTotalUserDeviceData() []structs.UserPropChartsData {
	data := make([]structs.UserPropChartsData, 0)

	// 从缓存中获取
	cacheKey := dbx.RedisPrefix(fmt.Sprintf("total_user_device_data"))
	cacheData := cache_main.Client().Get(context.Background(), cacheKey).Val()
	if cacheData != "" {
		_ = jsoniter.UnmarshalFromString(cacheData, &data)
		// return &data
	}

	db_zh_kernel_slave.Client().Model(model_zh_kernel.SysSmsRecord{}).
		Where("device != ''").
		Group("device").Select("device as name, count(*) as num").Order("num desc").Limit(10).Find(&data)

	// 保存到缓存中
	j, _ := jsoniter.MarshalToString(data)
	cache_main.Client().Set(context.Background(), cacheKey, j, 3*time.Hour)

	return data
}
